import java.util.HashMap;
import java.util.Scanner;

/**
 * 
 * Linux发行版的数量
 * 
 * 
 * 题目描述

Linux操作系统有多个发行版，distrowatch.com提供了各个发行版的资料。这些发行版互相存在关联，例如Ubuntu基于Debian开发，而Mint又基于Ubuntu开发，那么我们认为Mint同Debian也存在关联。

发行版集是一个或多个相关存在关联的操作系统发行版，集合内不包含没有关联的发行版。

给你一个 n * n 的矩阵 isConnected，其中 isConnected[i][j] = 1 表示第 i 个发行版和第 j 个发行版直接关联，而 isConnected[i][j] = 0 表示二者不直接相连。

返回最大的发行版集中发行版的数量。

输入描述
第一行输入发行版的总数量N，

之后每行表示各发行版间是否直接相关

输出描述
输出最大的发行版集中发行版的数量

备注
1 ≤ N ≤ 200

用例
输入	4
1 1 0 0
1 1 1 0
0 1 1 0
0 0 0 1
输出	3
说明	
Debian(1)和Unbuntu(2)相关
Mint(3)和Ubuntu(2)相关，
EeulerOS(4)和另外三个都不相关，
所以存在两个发行版集，发行版集中发行版的数量分别是3和1，所以输出3。


 */

 /*
  * 
  题目解析
本题可以利用并查集求解，本题要求的就是各个连通分量的节点数，并输出最大的连通分量的节点数。

如果大家对并查集还不了解，可以看下这个入门视频：
  */

public class Linux发行版的数量 {
    
    public static void main(String[] args) {
        
        Scanner sc = new Scanner(System.in);
 
        int n = sc.nextInt();
 
        int[][] matrix = new int[n][n];
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                matrix[i][j] = sc.nextInt();
            }
        }
 
        UnionFindSet ufs = new UnionFindSet(n);
 
        for (int i = 0; i < n; i++) {
            for (int j = i + 1; j < n; j++) { // j从i+1开始，是因为矩阵是对称的
                if (matrix[i][j] == 1) {
                    ufs.union(i, j);
                }
            }
        }
 
        // connected的key代表某个连通分量的顶级父节点，value代表该连通分量下的节点个数
        HashMap<Integer, Integer> connected = new HashMap<>();
        for (int i = 0; i < n; i++) {
            Integer fa = ufs.find(ufs.fa[i]);
            connected.put(fa, connected.getOrDefault(fa, 0) + 1);
        }
 
        // 返回最大节点数
        System.out.println(connected.values().stream().max((a, b) -> a - b).orElse(0));
    }
}
 
// 并查集实现
class UnionFindSet {
    int[] fa;
 
    public UnionFindSet(int n) {
        this.fa = new int[n];
        for (int i = 0; i < n; i++) this.fa[i] = i;
    }
 
    public int find(int x) {
        if (x != this.fa[x]) {
            return (this.fa[x] = this.find(this.fa[x]));
        }
        return x;
    }
 
    public void union(int x, int y) {
        int x_fa = this.find(x);
        int y_fa = this.find(y);
 
        if (x_fa != y_fa) {
            this.fa[y_fa] = x_fa;
        }
    }
}
